package com.ebt.m;

import android.os.SystemClock;
import android.text.TextUtils;

import com.ebt.m.commons.model.data.Constants;
import com.ebt.m.commons.model.http.APIsFactory;
import com.ebt.m.commons.utils.Logger;
import com.ebt.m.commons.utils.PrefKit;
import com.ebt.m.data.middle.EBTGetAdviceInfo;
import com.ebt.m.data.rxModel.api.EBTAPI;
import com.ebt.m.data.rxModel.api.GetUrlApi;
import com.ebt.m.data.rxModel.api.MsgAPI;
import com.ebt.m.data.rxModel.api.PolicyAPI;
import com.ebt.m.data.rxModel.apibean.DeviceIdParam;
import com.ebt.m.utils.ConfigData;
import com.google.gson.Gson;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONObject;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

/**
 * some initialization operation when app started
 */
public class AppInitService {

    private static final AppInitService APP_INIT_SERVICE = new AppInitService();
    private static Gson sGson;
    private static EventBus sBus;
    private static EBTAPI productNormalApi;
    private static EBTAPI ebtapi;
    private static PolicyAPI policyApi;
    private static MsgAPI msgApi;
    private static GetUrlApi getUrlApi;
    private static ExecutorService sSingleThreadExecutor;

    private AppInitService() {
    }

    public void initService() {
        sBus = new EventBus();
        sGson = new Gson();
        sSingleThreadExecutor = Executors.newSingleThreadExecutor();
        backGroundInit();
    }

    private void backGroundInit() {
        sSingleThreadExecutor.execute(new Runnable() {
            @Override
            public void run() {
                init();
                productNormalApi = APIsFactory.createOldApi(EBTAPI.class, ConfigData.PRODUCT_BASE_URL);
                getUrlApi = APIsFactory.createOldApi(GetUrlApi.class, ConfigData.API_BASE_URL);
                ebtapi = APIsFactory.getInstance().createService(EBTAPI.class, ConfigData.BASE_URL);
                policyApi = APIsFactory.getInstance().createService(PolicyAPI.class, ConfigData.BASE_URL);
                msgApi = APIsFactory.getInstance().createService(MsgAPI.class, ConfigData.BASE_URL);
            }
        });

    }

    public static void init() {
        getServerTime();
        getServerDeviceId();
    }

    private static void getServerDeviceId() {
        String localDeviceId = PrefKit.getString(AppContext.getInstance(), Constants.DEVICEID_KEY);
        if (TextUtils.isEmpty(localDeviceId)) {
            EBTAPI userApi = APIsFactory.createApiWithoutAuth(EBTAPI.class, ConfigData.BASE_URL);
            userApi.getDeviceId(createDeviceParam())
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(result -> {
                        try {
                            JSONObject jsonObject = new JSONObject(result.body().string());
                            String deviceId = jsonObject.getJSONObject("data").getString("deviceId");
                            if (!TextUtils.isEmpty(deviceId)) {
                                PrefKit.writeString(AppContext.getInstance(), Constants.DEVICEID_KEY, deviceId);
                            }
                        } catch (Exception e) {
                            Logger.e(e);
                        }
                    }, throwable -> {
                        throwable.printStackTrace();
                    });
        }
    }

    private static DeviceIdParam createDeviceParam() {
        DeviceIdParam idParam = new DeviceIdParam();
        idParam.appOs = EBTGetAdviceInfo.getSystemVersion();
        idParam.appVersion = EBTGetAdviceInfo.getAppVersionName();
        idParam.macAddress = EBTGetAdviceInfo.getMacAddress();
        idParam.androidId = EBTGetAdviceInfo.getAndroidId();
        idParam.deviceId = EBTGetAdviceInfo.getDeviceId();
        return idParam;
    }

    private static void getServerTime() {
        EBTAPI userApi = APIsFactory.createApiWithoutAuth(EBTAPI.class, ConfigData.BASE_URL);
        userApi.getServerTime()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(result -> {
                    try {
                        JSONObject jsonObject = new JSONObject(result.body().string());
                        long serverTime = jsonObject.getJSONObject("data").getLong("dateTime");
                        AppContext.deltaTime = serverTime - SystemClock.elapsedRealtime();
                    } catch (Exception e) {
                        Logger.e(e);
                        AppContext.deltaTime = 0;
                    }
                }, throwable -> AppContext.deltaTime = 0);
    }

    public static AppInitService getInstance() {
        return APP_INIT_SERVICE;
    }

    public static EventBus getBus() {
        return sBus;
    }

    public static EBTAPI getProductNormalApi() {
        return productNormalApi;
    }

    public static GetUrlApi getUrlApi() {
        return getUrlApi;
    }


    public static Gson getGson() {
        return sGson;
    }

    public static EBTAPI getEbtApi() {
        if (ebtapi == null)
            ebtapi = APIsFactory.getInstance().createService(EBTAPI.class, ConfigData.BASE_URL);
        return ebtapi;
    }

    public static ExecutorService getSingleThreadExecutor() {
        return sSingleThreadExecutor;
    }

    public static PolicyAPI getPolicyApi() {
        if (policyApi == null)
            policyApi = APIsFactory.getInstance().createService(PolicyAPI.class, ConfigData.BASE_URL);
        return policyApi;
    }

    public synchronized static MsgAPI getMsgApi() {
        if (msgApi == null)
            msgApi = APIsFactory.getInstance().createService(MsgAPI.class, ConfigData.BASE_URL);
        return msgApi;
    }
}
